package cn.yangliu.controller;

import cn.yangliu.entity.ToolApplicationEvent;
import cn.yangliu.model.CallbackParams;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.Objects;

/**
 * The type of ascii-mp-home.
 * websocket 处理
 * <p>
 * .
 *
 * @author 杨柳
 */
@ServerEndpoint("/websocket")
@Component
public class WebSocketHandler implements ApplicationListener<ToolApplicationEvent> {

    private static Session session;

    /**
     * current class's static member
     * The constant LOGGER.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketHandler.class);

    /**
     * On open.
     *
     * @param session the session
     * @throws Exception the exception
     */
    @OnOpen
    public void onOpen(Session session) throws Exception {
        WebSocketHandler.session = session;
        LOGGER.info("Open a websocket");
    }

    /**
     * On close.
     */
    @OnClose
    public void onClose(Session session) {
        LOGGER.info("Close a websocket. ");
    }

    /**
     * On message.
     *
     * @param message the message
     * @param session the session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        LOGGER.info("Receive a message from client: " + message);
    }

    /**
     * On error.
     *
     * @param session the session
     * @param error   the error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        LOGGER.error("Error while websocket. ", error);
    }

    /**
     * Send message.
     *
     * @param message the message
     * @throws Exception the exception
     */
    public void sendMessage(String message) throws Exception {
        if (session.isOpen()) {
            LOGGER.info("send monitor data");
            session.getBasicRemote().sendText(message);
        }
    }

    @Override
    public void onApplicationEvent(ToolApplicationEvent event) {
        CallbackParams<?> data = (CallbackParams<?>)event.getSource();
        if (Objects.isNull(session) ) {
            LOGGER.info("websocket session dose not open, notify {} failed", data.getFunctionName());
            return;
        }

        try {
            if (session.isOpen()) {
                LOGGER.info("send monitor data");
                LOGGER.info("调用前端方法{}", data.getFunctionName());
                session.getBasicRemote().sendText(JSON.toJSONString(data));
            }
        } catch (Exception e) {
            LOGGER.error("callback {} function failed.", data.getFunctionName(), e);
        }
    }
}
